package com.anjho.dao;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.NoResultException;
import javax.persistence.Persistence;
import javax.persistence.Query;

public abstract class DAOGeneric implements Serializable {

	private static final long serialVersionUID = -2816886614097588323L;
	protected EntityManager entityManager;

	protected DAOGeneric() {
		EntityManagerFactory entityManagerFactory = Persistence
				.createEntityManagerFactory("Anjho");
		entityManager = entityManagerFactory.createEntityManager();
	}

	public EntityManager getEntityManager() {
		return this.entityManager;
	}

	public void insert(Object object) {

		try {
			entityManager.getTransaction().begin();
			entityManager.persist(object);
			entityManager.flush();
			entityManager.getTransaction().commit();
		} catch (Exception e) {
			if (entityManager.getTransaction().isActive()) {
				entityManager.getTransaction().rollback();
			}
			throw e;
		}
	}

	public void delete(Object object) throws Exception {
		try {
			entityManager.getTransaction().begin();
			object = entityManager.merge(object);
			entityManager.remove(object);
			entityManager.flush();
			entityManager.getTransaction().commit();
		} catch (Exception e) {
			if (entityManager.getTransaction().isActive()) {
				entityManager.getTransaction().rollback();
			}
			throw e;
		}
	}

	public void update(Object object) throws Exception {
		try {
			entityManager.getTransaction().begin();
			entityManager.merge(object);
			entityManager.flush();
			entityManager.getTransaction().commit();
		} catch (Exception e) {
			if (entityManager.getTransaction().isActive()) {
				entityManager.getTransaction().rollback();
			}
			throw e;
		}
	}

	public List<?> getList(String namedQuery) throws Exception {
		List<?> objectList = null;
		try {
			objectList = entityManager.createNamedQuery(namedQuery)
					.getResultList();
		} catch (NoResultException e) {
			objectList = new ArrayList<>();
		} catch (Exception e) {
			throw e;
		}
		return objectList;
	}

	public List<?> getListByParameter(String[] parameters, Object[] values,
			String namedQuery) throws Exception {
		if (parameters.length != values.length) {
			throw new Exception(
					"A quantidade de parâmetros informados é diferente da quantidade de valores");
		}
		Query query = entityManager.createNamedQuery(namedQuery);
		int currentValue = 0;
		for (String parameter : parameters) {
			query.setParameter(parameter, values[currentValue]);
			currentValue++;
		}
		List<?> objectList = null;
		try {
			objectList = query.getResultList();
		} catch (NoResultException e) {
			objectList = new ArrayList<>();
		} catch (Exception e) {
			throw e;
		}
		return objectList;
	}

	public Object getObjectByParameter(String[] parameters, Object[] values,
			String namedQuery) throws Exception {
		if (parameters.length != values.length) {
			throw new Exception(
					"A quantidade de parâmetros informados é diferente da quantidade de valores");
		}
		Query query = entityManager.createNamedQuery(namedQuery);
		int currentValue = 0;
		for (String parameter : parameters) {
			query.setParameter(parameter, values[currentValue]);
			currentValue++;
		}
		Object object = null;
		try {
			object = query.getSingleResult();
		} catch (Exception e) {
			throw e;
		}
		return object;
	}
}
